`timescale 1ns / 1ps 
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/02/26 10:27:13
// Design Name:
// Module Name: cmd_coder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module cmd_coder(
           clk,
           resetb,
           ie,
           idat,
           oe,
           cmd,
           odat
       );
localparam A = 8'd1;
localparam B = 8'd2;
localparam C = 8'd3;
localparam D = 8'd4;
localparam E = 8'd5;
localparam F = 8'd6;
localparam G = 8'd7;
localparam H = 8'd8;
localparam I = 8'd9;
localparam J = 8'd10;
localparam K = 8'd11;
localparam L = 8'd12;
localparam M = 8'd13;
localparam N = 8'd14;
localparam O = 8'd15;
localparam P = 8'd16;
localparam Q = 8'd17;
localparam R = 8'd18;
localparam S = 8'd19;
localparam T = 8'd20;
localparam U = 8'd21;
localparam V = 8'd22;
localparam W = 8'd23;
localparam X = 8'd24;
localparam Y = 8'd25;
localparam Z = 8'd26;
localparam _0 = 8'd27;
localparam _1 = 8'd28;
localparam _2 = 8'd29;
localparam _3 = 8'd30;
localparam _4 = 8'd31;
localparam _5 = 8'd32;
localparam _6 = 8'd33;
localparam _7 = 8'd34;
localparam _8 = 8'd35;
localparam _9 = 8'd236;
localparam BKSP = 8'd37;
localparam SPACE = 8'd38;
localparam ENTER = 8'd39;

parameter DW = 8 ;
parameter AW = 4;
parameter DP = 1 << AW;

input clk;
input resetb;
input ie;
input [7: 0] idat;
output oe;
output [1: 0] cmd;
output [7: 0] odat;
parameter ck2q = 1;

wire STOP = (idat == ENTER);
wire BACK = (idat == BKSP);

//spram_fifo
wire wr = ie & ~(STOP | BACK);
wire empty;
wire rd = (STOP & ~empty);
wire [AW - 1: 0] addr;
wire [DW - 1: 0] dat_w;

spram_cmd u_spram(
              .clk(clk),
              .ie(wr),
              .idat(idat),
              .oe(rd),
              .odat(dat_w),
              .addr(addr)
          );

reg [AW - 1: 0] waddr;
wire [AW - 1: 0] waddr_p1 = waddr + 1'b1;

always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			waddr <= #ck2q 0;
		else if (ie & ~STOP)
			begin
				if (BACK)
					begin
						if (!empty)
							waddr <= #ck2q waddr - 1'b1;
					end
				else
					waddr <= #ck2q waddr_p1;
			end
	end

reg [AW - 1: 0] raddr;
wire [AW - 1: 0] raddr_p1 = raddr + 1'b1;
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			raddr <= #ck2q 0;
		else if (rd)
			raddr <= #ck2q raddr_p1;
	end

assign empty = (waddr == raddr);
assign addr = rd ? raddr : waddr;

//cmd_switch
reg rd_d1, rd_d2;
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			begin
				rd_d1 <= #ck2q 0;
				rd_d2 <= #ck2q 0;
			end
		else
			begin
				rd_d1 <= #ck2q rd;
				rd_d2 <= #ck2q rd_d1;
			end
	end

wire en = rd_d2 & ~rd_d1;
reg [3: 0] en_d;
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			en_d <= #ck2q 4'd0;
		else
			en_d <= #ck2q {en_d[2: 0] , en};
	end

assign oe = en_d[0] | en_d[1] | en_d[2] | en_d[3];

reg [DW - 1: 0] cmd_d0, cmd_d1, cmd_d2, cmd_d3, cmd_d4, cmd_d5, cmd_d6, cmd_d7,
    cmd_d8, cmd_d9, cmd_d10, cmd_d11, cmd_d12, cmd_d13, cmd_d14, cmd_d15;

always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			begin
				{cmd_d0, cmd_d1, cmd_d2, cmd_d3, cmd_d4, cmd_d5, cmd_d6, cmd_d7,
				 cmd_d8, cmd_d9, cmd_d10, cmd_d11, cmd_d12, cmd_d13, cmd_d14, cmd_d15} <= #ck2q
				{dat_w, cmd_d0, cmd_d1, cmd_d2, cmd_d3, cmd_d4, cmd_d5, cmd_d6, cmd_d7,
				 cmd_d8, cmd_d9, cmd_d10, cmd_d11, cmd_d12, cmd_d13, cmd_d14};
			end
		else if (rd_d1)
			begin
				{cmd_d0, cmd_d1, cmd_d2, cmd_d3, cmd_d4, cmd_d5, cmd_d6, cmd_d7,
				 cmd_d8, cmd_d9, cmd_d10, cmd_d11, cmd_d12, cmd_d13, cmd_d14, cmd_d15} <= #ck2q
				{dat_w, cmd_d0, cmd_d1, cmd_d2, cmd_d3, cmd_d4, cmd_d5, cmd_d6, cmd_d7,
				 cmd_d8, cmd_d9, cmd_d10, cmd_d11, cmd_d12, cmd_d13, cmd_d14};
			end
		else
			begin
				{cmd_d0, cmd_d1, cmd_d2, cmd_d3, cmd_d4, cmd_d5, cmd_d6, cmd_d7,
				 cmd_d8, cmd_d9, cmd_d10, cmd_d11, cmd_d12, cmd_d13, cmd_d14, cmd_d15} <= #ck2q 0;
			end
	end
wire [16 * 8 - 1: 0] dat_cmd = {cmd_d15, cmd_d14, cmd_d13, cmd_d12, cmd_d11, cmd_d10,
                                cmd_d9, cmd_d8, cmd_d7, cmd_d6, cmd_d5, cmd_d4, cmd_d3, cmd_d2, cmd_d1, cmd_d0};

parameter [16 * 8 - 1: 0] T_0 = {{14 * 8{1'b0}}, T, _0} ;
parameter [16 * 8 - 1: 0] T_10 = {{13 * 8{1'b0}}, T, _1, _0};
parameter [16 * 8 - 1: 0] T_20 = {{13 * 8{1'b0}}, T, _2, _0};
parameter [16 * 8 - 1: 0] T_30 = {{13 * 8{1'b0}}, T, _3, _0};
parameter [16 * 8 - 1: 0] T_40 = {{13 * 8{1'b0}}, T, _4, _0};
parameter [16 * 8 - 1: 0] T_50 = {{13 * 8{1'b0}}, T, _5, _0};
parameter [16 * 8 - 1: 0] T_60 = {{13 * 8{1'b0}}, T, _6, _0};
parameter [16 * 8 - 1: 0] T_70 = {{13 * 8{1'b0}}, T, _7, _0};
parameter [16 * 8 - 1: 0] T_80 = {{13 * 8{1'b0}}, T, _8, _0};
parameter [16 * 8 - 1: 0] T_90 = {{13 * 8{1'b0}}, T, _9, _0};
parameter [16 * 8 - 1: 0] T_100 = {{12 * 8{1'b0}}, T, _1, _0, _0};
parameter [16 * 8 - 1: 0] T_110 = {{12 * 8{1'b0}}, T, _1, _1, _0};
parameter [16 * 8 - 1: 0] T_120 = {{12 * 8{1'b0}}, T, _1, _2, _0};
parameter [16 * 8 - 1: 0] T_130 = {{12 * 8{1'b0}}, T, _1, _3, _0};
parameter [16 * 8 - 1: 0] T_140 = {{12 * 8{1'b0}}, T, _1, _4, _0};
parameter [16 * 8 - 1: 0] T_150 = {{12 * 8{1'b0}}, T, _1, _5, _0};
parameter [16 * 8 - 1: 0] T_160 = {{12 * 8{1'b0}}, T, _1, _6, _0};
parameter [16 * 8 - 1: 0] T_170 = {{12 * 8{1'b0}}, T, _1, _7, _0};
parameter [16 * 8 - 1: 0] T_180 = {{12 * 8{1'b0}}, T, _1, _8, _0};
parameter [16 * 8 - 1: 0] T_190 = {{12 * 8{1'b0}}, T, _1, _9, _0};
parameter [16 * 8 - 1: 0] T_200 = {{12 * 8{1'b0}}, T, _2, _0, _0};
parameter [16 * 8 - 1: 0] T_210 = {{12 * 8{1'b0}}, T, _2, _1, _0};
parameter [16 * 8 - 1: 0] T_220 = {{12 * 8{1'b0}}, T, _2, _2, _0};
parameter [16 * 8 - 1: 0] T_230 = {{12 * 8{1'b0}}, T, _2, _3, _0};
parameter [16 * 8 - 1: 0] T_240 = {{12 * 8{1'b0}}, T, _2, _4, _0};
parameter [16 * 8 - 1: 0] SLOW = {{12 * 8{1'b0}}, S, L, O, W};
parameter [16 * 8 - 1: 0] FAST = {{12 * 8{1'b0}}, F, A, S, T};

reg [1: 0] cmd;
reg [7: 0] odat;
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			begin
				cmd <= #ck2q 2'd0;
				odat <= #ck2q 8'd40;
			end
		else if (en)
			begin
				if (dat_cmd == T_0)
					begin
						odat <= #ck2q 8'd0;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_10)
					begin
						odat <= #ck2q 8'd10;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_20)
					begin
						odat <= #ck2q 8'd20;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_30)
					begin
						odat <= #ck2q 8'd30;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_40)
					begin
						odat <= #ck2q 8'd40;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_50)
					begin
						odat <= #ck2q 8'd50;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_60)
					begin
						odat <= #ck2q 8'd60;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_70)
					begin
						odat <= #ck2q 8'd70;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_80)
					begin
						odat <= #ck2q 8'd80;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_90)
					begin
						odat <= #ck2q 8'd90;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_100)
					begin
						odat <= #ck2q 8'd100;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_110)
					begin
						odat <= #ck2q 8'd110;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_120)
					begin
						odat <= #ck2q 8'd120;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_130)
					begin
						odat <= #ck2q 8'd130;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_140)
					begin
						odat <= #ck2q 8'd140;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_150)
					begin
						odat <= #ck2q 8'd150;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_160)
					begin
						odat <= #ck2q 8'd160;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_170)
					begin
						odat <= #ck2q 8'd170;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_180)
					begin
						odat <= #ck2q 8'd180;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_190)
					begin
						odat <= #ck2q 8'd190;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_200)
					begin
						odat <= #ck2q 8'd200;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_210)
					begin
						odat <= #ck2q 8'd210;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_220)
					begin
						odat <= #ck2q 8'd220;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_230)
					begin
						odat <= #ck2q 8'd230;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == T_240)
					begin
						odat <= #ck2q 8'd240;
						cmd <= #ck2q 2'd2;
					end
				if (dat_cmd == SLOW)
					begin
						odat <= #ck2q 8'd1;
						cmd <= #ck2q 2'd1;
					end
				if (dat_cmd == FAST)
					begin
						odat <= #ck2q 8'd2;
						cmd <= #ck2q 2'd1;
					end
			end
	end
endmodule
